package com.demo.gulimall.order.config;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * @author Chen Yuan
 * @create 2023-06-26  9:20
 */
@Configuration
@Slf4j
public class MyRabbitConfig {
	@Autowired
	private RabbitTemplate rabbitTemplate;

	// 定制 RabbitTemplate
	@PostConstruct // MyRabbitConfig 对象创建完成以后, 执行当前方法
	public void initRabbitTemplate(){

		// 设置 confirmCallback
		rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
			/**
			 * 只要消息抵达 Broker 就 ACK = true
			 *
			 * 只要进入这个方法则表示服务器收到了消息, 则将状态更新到 MQ 消息表
			 *
			 * @param correlationData 当前消息的唯一关联数据(可以认为是消息的唯一ID)
			 * @param b 消息是否成功收到
			 * @param s 失败原因
			 */
			@Override
			public void confirm(CorrelationData correlationData, boolean b, String s) {
				log.info("--> ConfirmCallback .. correlationData:{}, ack:{}, reason:{}", JSON.toJSONString(correlationData), b, s);
			}
		});

		// 设置 returnCallback
		rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
			/**
			 * 消息投递成功不会触发
			 * 只要消息没有投递给指定的队列, 就触发这个失败回调
			 *
			 * 只要进入到这个方法, 则消息没有成功进入队列, 即发送失败了, 则将发送失败的状态更新到消息表
			 *
			 * @param message 投递失败的消息的详细信息
			 * @param i 状态码
			 * @param s 回复的文本内容
			 * @param s1 当时消息发给哪个交换机
			 * @param s2 当时消息指定的路由键
			 */
			@Override
			public void returnedMessage(Message message, int i, String s, String s1, String s2) {
				log.info("--> ReturnCallback .. message:{}, code:{}, text:{}, exchange:{}, routingKey:{}", JSON.toJSONString(message), i, s, s1, s2);
			}
		});
	}
}
